package com.pansoft.xbrl.xbrljson.convert;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.pansoft.xbrl.xbrljson.config.XbrlJsonConfigMgr;
import com.pansoft.xbrl.xbrljson.config.model.JsonConfigItem;
import com.pansoft.xbrl.xbrljson.config.model.XbrlJsonConfig;
import com.pansoft.xbrl.xbrljson.constant.XbrlConfigConstant;
import com.pansoft.xbrl.xbrljson.reader.XbrlReader;
import com.pansoft.xbrl.xbrljson.reader.impl.BaseXbrlReader;
import com.pansoft.xbrl.xbrljson.util.StringUtil;

import java.util.List;

/**
 * xbrl数据到json数据转换
 * @author coolmayi
 * @create 2021/9/6
 */
public class XbrlToJson {

    /**
     * xbrl输出
     */
    private XbrlReader xbrlReader = new BaseXbrlReader();

    /**
     * 根据实例文档路径返回 json对象
     * @param xbrlFilePath
     * @param configId
     * @return
     */
    public JSONObject convertXbrlJsonDataWithPath (String xbrlFilePath, String configId) {

        try {
            JSONObject jsonObject = xbrlReader.readXbrlDataWithPath(xbrlFilePath);
            return this.convertXbrlJsonData(jsonObject, configId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 根据xml内容 返回json对象
     * @param xbrlXml
     * @param configId
     * @return
     */
    public JSONObject convertXbrlJsonData(String xbrlXml, String configId) {
        try {
            JSONObject jsonObject = xbrlReader.readXbrlDataWithXml(xbrlXml);
            return this.convertXbrlJsonData(jsonObject, configId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 根据配置编号获取json对象
     * @param xbrlJsonData
     * @param configId
     * @return
     */
    public JSONObject convertXbrlJsonData(JSONObject xbrlJsonData, String configId) {

        if (xbrlJsonData == null) {
            return null;
        }

        if (StringUtil.isBlank(configId)) {
            return null;
        }
        XbrlJsonConfig configObject = XbrlJsonConfigMgr.getInstance().getConfigObject(configId);
        if (configObject == null) {
            System.out.println("没有找到配置文件信息，配置编号["+configId+"]");
            return null;
        }

        JsonConfigItem jsonConfigItem = configObject.getJsonConfig();
        if (jsonConfigItem == null) {
            return null;
        }

        JSONObject jsonObject = new JSONObject(true);
        // 创建json对象
        this.buildJsonObject(jsonConfigItem, xbrlJsonData, jsonObject);

        return jsonObject;
    }

    /**
     * 创建json对象
     * 元组下级层级不再进行拆分，元组根节点为拆分最小单元项
     * @param jsonConfigItem
     * @param xbrlJsonData
     * @param parentJsonObject
     */
    private void buildJsonObject(JsonConfigItem jsonConfigItem, JSONObject xbrlJsonData, JSONObject parentJsonObject) {

        if (jsonConfigItem == null || xbrlJsonData == null) {
            return ;
        }

        List<JsonConfigItem> childList =  jsonConfigItem.getChildList();
        if (childList == null || childList.size() == 0) {
            return ;
        }

        String fieldName;
        String elementName;
        String elementType ;
        // 遍历下级节点
        for (JsonConfigItem item : childList) {
            fieldName = item.getFieldName();
            elementName = item.getElementNsName()  +":" + item.getElementName();
            elementType = item.getElementValueType();
            // 下级节点
            List<JsonConfigItem> nextChildList = item.getChildList();
            if (XbrlConfigConstant.elementValueType_Tuple.equals(elementType)) {
                // 元组类型
                Object obj = xbrlJsonData.get(elementName);
                if (obj != null && obj instanceof JSONArray) {
                    JSONArray objList = (JSONArray)obj;
                    JSONArray tupleList = new JSONArray();
                    parentJsonObject.put(fieldName, tupleList);
                    for (Object tupleItem : objList) {
                        JSONObject parentNode = new JSONObject(true);
                        tupleList.add(parentNode);
                        this.buildJsonObject(item, (JSONObject)tupleItem, parentNode);
                    }
                }
            } else {
                // 其他类型
                if (nextChildList != null && nextChildList.size() > 0) {
                    // 存在下级
                    JSONObject parentNode = new JSONObject(true);
                    parentJsonObject.put(fieldName, parentNode);
                    this.buildJsonObject(item, xbrlJsonData, parentNode);
                } else {
                    //
                    Object obj = xbrlJsonData.get(elementName);
                    if (obj != null) {
                        parentJsonObject.put(fieldName, obj);
                    }
                }
            }
        }

    }


    public XbrlReader getXbrlReader() {
        return xbrlReader;
    }

    public void setXbrlReader(XbrlReader xbrlReader) {
        this.xbrlReader = xbrlReader;
    }

}
